/**
 ******************************************************************************
 * @file           : basic_usage.c
 * @brief          : Error Handler 基本使用示例
 ******************************************************************************
 * @attention
 *
 * 本文件展示 Error Handler 的各种使用方法，包括：
 * - 错误码返回
 * - 错误检查宏
 * - 错误传播
 * - 错误日志
 * - 重试机制
 * - 实际应用示例
 *
 ******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "error_handler.h"
#include <stdio.h>

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/* ============================================================================
 * 示例1：基本错误返回
 * ========================================================================= */

/**
 * @brief       示例函数：基本错误返回
 *
 * @param[in]   value: 输入值
 * @param[out]  result: 输出结果指针
 *
 * @retval      ERR_OK: 成功
 * @retval      ERR_NULL_POINTER: 空指针
 * @retval      ERR_OUT_OF_RANGE: 超出范围
 */
ErrorCode_t Example_BasicErrorReturn(float value, float *result)
{
    /* 检查空指针 */
    if (result == NULL)
    {
        return ERR_NULL_POINTER;
    }
    
    /* 检查范围 */
    if (value < 0.0f || value > 100.0f)
    {
        return ERR_OUT_OF_RANGE;
    }
    
    /* 正常处理 */
    *result = value * 2.0f;
    
    return ERR_OK;
}

/* ============================================================================
 * 示例2：使用便捷宏
 * ========================================================================= */

/**
 * @brief       示例函数：使用CHECK宏简化错误处理
 *
 * @param[in]   value: 输入值
 * @param[out]  result: 输出结果指针
 *
 * @retval      ERR_OK: 成功
 * @retval      ERR_NULL_POINTER: 空指针
 * @retval      ERR_OUT_OF_RANGE: 超出范围
 */
ErrorCode_t Example_WithMacros(float value, float *result)
{
    /* 使用宏简化空指针检查 */
    CHECK_NULL_POINTER(result);
    
    /* 使用宏简化参数检查 */
    CHECK_PARAM(value >= 0.0f && value <= 100.0f);
    
    /* 或者使用范围检查宏 */
    CHECK_RANGE(value, 0.0f, 100.0f);
    
    /* 正常处理 */
    *result = value * 2.0f;
    
    return ERR_OK;
}

/* ============================================================================
 * 示例3：错误传播
 * ========================================================================= */

/**
 * @brief       底层函数
 *
 * @param[in]   data: 数据指针
 *
 * @retval      ErrorCode_t: 错误码
 */
static ErrorCode_t LowLevelFunction(uint8_t *data)
{
    CHECK_NULL_POINTER(data);
    
    /* 模拟可能失败的操作 */
    if (*data == 0)
    {
        RETURN_ERROR(ERR_INVALID_PARAM);
    }
    
    return ERR_OK;
}

/**
 * @brief       中层函数：调用底层函数并传播错误
 *
 * @param[in]   data: 数据指针
 *
 * @retval      ErrorCode_t: 错误码
 */
static ErrorCode_t MiddleLevelFunction(uint8_t *data)
{
    /* 调用底层函数，如果出错则自动返回 */
    CHECK_ERROR(LowLevelFunction(data));
    
    /* 继续处理... */
    
    return ERR_OK;
}

/**
 * @brief       高层函数：完整的错误处理
 *
 * @param[in]   data: 数据指针
 *
 * @retval      ErrorCode_t: 错误码
 */
ErrorCode_t Example_ErrorPropagation(uint8_t *data)
{
    ErrorCode_t result;
    
    /* 调用中层函数 */
    result = MiddleLevelFunction(data);
    
    /* 检查结果并处理 */
    if (result != ERR_OK)
    {
        printf("Error occurred: %s\n", Error_CodeToString(result));
        return result;
    }
    
    return ERR_OK;
}

/* ============================================================================
 * 示例4：EEPROM写入带重试
 * ========================================================================= */

/**
 * @brief       模拟EEPROM写入函数
 *
 * @param[in]   addr: 地址
 * @param[in]   data: 数据指针
 * @param[in]   size: 数据大小
 *
 * @retval      ErrorCode_t: 错误码
 */
static ErrorCode_t SimulatedEEPROM_Write(uint16_t addr, const uint8_t *data, size_t size)
{
    CHECK_NULL_POINTER(data);
    CHECK_PARAM(size > 0);
    
    /* 模拟可能失败的写入 */
    static uint8_t fail_count = 0;
    
    if (fail_count < 2)
    {
        fail_count++;
        RETURN_ERROR(ERR_EEPROM_WRITE_FAIL);
    }
    
    fail_count = 0;
    return ERR_OK;
}

/**
 * @brief       带重试机制的EEPROM写入
 *
 * @param[in]   addr: 地址
 * @param[in]   data: 数据指针
 * @param[in]   size: 数据大小
 *
 * @retval      ErrorCode_t: 错误码
 */
ErrorCode_t Example_EEPROMWriteWithRetry(uint16_t addr, const uint8_t *data, size_t size)
{
    #define MAX_RETRY_COUNT     3
    
    ErrorCode_t result;
    uint8_t retry;
    
    CHECK_NULL_POINTER(data);
    
    /* 重试机制 */
    for (retry = 0; retry < MAX_RETRY_COUNT; retry++)
    {
        result = SimulatedEEPROM_Write(addr, data, size);
        
        if (result == ERR_OK)
        {
            /* 写入成功 */
            return ERR_OK;
        }
        
        /* 短暂延时后重试 */
        // TODO: 替换为你的延时函数
        // 例如: HAL_Delay(10) 或 delay_ms(10)
    }
    
    /* 重试失败 */
    printf("EEPROM write failed after %d retries\n", MAX_RETRY_COUNT);
    RETURN_ERROR(ERR_EEPROM_WRITE_FAIL);
}

/* ============================================================================
 * 示例5：错误日志使用
 * ========================================================================= */

/**
 * @brief       演示错误日志功能
 *
 * @param       无
 *
 * @retval      无
 */
void Example_ErrorLogging(void)
{
    ErrorCode_t result;
    float output;
    uint8_t data = 0;
    
    printf("\n=== Error Logging Example ===\n");
    
    /* 清除之前的错误日志 */
    Error_ClearLog();
    
    /* 故意触发一些错误 */
    result = Example_BasicErrorReturn(-10.0f, &output);
    if (result != ERR_OK)
    {
        printf("Error 1: %s\n", Error_CodeToString(result));
    }
    
    result = Example_BasicErrorReturn(50.0f, NULL);
    if (result != ERR_OK)
    {
        printf("Error 2: %s\n", Error_CodeToString(result));
    }
    
    result = Example_ErrorPropagation(&data);
    if (result != ERR_OK)
    {
        printf("Error 3: %s\n", Error_CodeToString(result));
    }
    
    /* 打印错误日志 */
    Error_PrintLog();
    
    /* 获取错误统计 */
    printf("NULL pointer errors: %lu\n", Error_GetCount(ERR_NULL_POINTER));
    printf("Out of range errors: %lu\n", Error_GetCount(ERR_OUT_OF_RANGE));
    printf("Total errors: %lu\n", Error_GetTotalCount());
}

/* ============================================================================
 * 示例6：实际应用 - 流量测量模块
 * ========================================================================= */

/**
 * @brief       示例：流量值验证和累计
 *
 * @param[in]   flow: 流量值
 * @param[in,out] accumulated: 累计流量指针
 *
 * @retval      ERR_OK: 成功
 * @retval      ERR_NULL_POINTER: 空指针
 * @retval      ERR_FLOW_OUT_OF_RANGE: 流量超出范围
 * @retval      ERR_FLOW_ACCUM_OVERFLOW: 累计溢出
 */
ErrorCode_t Example_FlowAccumulate(float flow, uint32_t *accumulated)
{
    #define FLOW_MIN    0.0f
    #define FLOW_MAX    1000.0f
    #define ACCUM_MAX   999999999UL
    
    /* 参数检查 */
    CHECK_NULL_POINTER(accumulated);
    
    /* 流量范围检查 */
    if (flow < FLOW_MIN || flow > FLOW_MAX)
    {
        RETURN_ERROR(ERR_FLOW_OUT_OF_RANGE);
    }
    
    /* 溢出检查 */
    if (*accumulated > ACCUM_MAX - (uint32_t)flow)
    {
        RETURN_ERROR(ERR_FLOW_ACCUM_OVERFLOW);
    }
    
    /* 累计 */
    *accumulated += (uint32_t)flow;
    
    return ERR_OK;
}

/* Exported functions --------------------------------------------------------*/

/**
 * @brief       运行所有示例
 *
 * @param       无
 *
 * @retval      无
 */
void ErrorExample_RunAll(void)
{
    printf("\n========================================\n");
    printf("  Error Handling System Examples\n");
    printf("========================================\n");
    
    /* 运行错误日志示例 */
    Example_ErrorLogging();
    
    printf("\n=== All examples completed ===\n\n");
}
